home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / pc / files / t_unix / j109lxa4.tar / mailfor.c < prev    next >
C/C++ Source or Header  |  1994-06-04  |  9KB  |  408 lines

  1. /* The following code will broadcast 'Mail for:' beacons
  2.  * for private users with unread mail on a regular interval
  3.  *
  4.  * Also contains the commands to set the R: header read options
  5.  * with the 'bulletin' command.
  6.  *
  7.  * original: 920306
  8.  * rewritten: 920326
  9.  * Copyright 1992, Johan. K. Reinalda, WG7J/PA3DIS
  10.  * Permission granted for non-commercial use only!
  11.  */
  12. #include <stdio.h>
  13. #ifdef MSDOS
  14. #include <dir.h>
  15. #include <dos.h>
  16. #endif
  17. #ifdef UNIX
  18. #include <ctype.h>
  19. #endif
  20. #include "global.h"
  21. #include "files.h"
  22. #include "dirutil.h"
  23. #include "bm.h"
  24. #include "cmdparse.h"
  25. #include "timer.h"
  26. #include "pktdrvr.h"
  27. #include "ax25.h"
  28. #include "mailfor.h"
  29. #include "socket.h"
  30.  
  31. #ifdef MAILFOR
  32. #ifdef AX25
  33.  
  34. #define MAXMFLEN 256
  35. static struct timer Mftimer;
  36. static char ax_mftext[MAXMFLEN+1] = "Mail for:";
  37. #define DEFMFLEN 9
  38. int mflen = DEFMFLEN; /*Initial lenght of mail-for string*/
  39.  
  40. /* List of area names to exclude from mail-for beacon */
  41. struct no_mf {
  42.     struct no_mf *next;
  43.     char area[9];
  44. };
  45. #define NULLMF (struct no_mf *)0
  46. struct no_mf *No_mf = NULLMF;
  47.  
  48. /*Read a private message area, searching for unread mail
  49.  *this is indicated by the lack of a 'Status: Y' line
  50.  */
  51. int
  52. #ifdef PROTOTYPES
  53. checknewmail(char *area)
  54. #else
  55. checknewmail(area)
  56. char *area;
  57. #endif
  58. {
  59.     FILE *fp;
  60.     char buf[80];
  61.     int unread;
  62.  
  63.     sprintf(buf,"%s/%s.txt",Mailspool,area);
  64.     /*Open area file*/
  65.     if((fp = fopen(buf,READ_TEXT)) != NULLFILE) {
  66.     while(fgets(buf,sizeof(buf),fp) != NULLCHAR) {
  67.         /* scan for begining of a message */
  68.         if(strncmp(buf,"From ",5) == 0) {
  69.         /*let others runs too !*/
  70.         pwait(NULL);
  71.         /*Now scan all the header lines,
  72.          *looking for the status line
  73.          */
  74.         unread = 1;
  75.         while(fgets(buf,sizeof(buf),fp) != NULLCHAR) {
  76.             if(*buf == '\n')
  77.             /* last header line */
  78.             break;
  79.             if(htype(buf) == STATUS) {
  80.             /*found a read message */
  81.             unread = 0;
  82.             break;
  83.             }
  84.         }
  85.         /*done with headers. was this was unread ?*/
  86.         if(unread) {
  87.             fclose(fp);
  88.             return 1;
  89.         }
  90.         }
  91.     }
  92.     fclose(fp);
  93.     }
  94.     /* None found !*/
  95.     return 0;
  96. }
  97.  
  98. /* Check name with exclude list;
  99.  * returns 1 if found, 0 if not
  100.  */
  101. int
  102. #ifdef PROTOTYPES
  103. mf_exclude(char *name)
  104. #else
  105. mf_exclude(name)
  106. char *name;
  107. #endif
  108. {
  109.     struct no_mf *nm;
  110.  
  111.     /*Now check the 'exclude' list*/
  112.     for(nm=No_mf;nm!=NULLMF;nm=nm->next) {
  113.     if(!stricmp(nm->area,name))
  114.         return 1;
  115.     }
  116.     return 0;
  117. }
  118.  
  119. int
  120. #ifdef PROTOTYPES
  121. setmailfor(void)
  122. #else
  123. setmailfor()
  124. #endif
  125. {
  126.     char buf[80];
  127.     struct ffblk ff;
  128. #ifdef UNIX
  129.     int c, d;
  130. #endif
  131.  
  132.     sprintf(buf,"%s/*.txt",Mailspool);
  133.     if (findfirst(buf, &ff, 0) == 0) {
  134.     do {
  135.         pwait(NULL);    /* Let others run */
  136.         *(strchr(ff.ff_name,'.')) = '\0';
  137.         /*must be private mail area, and not on exclude list !*/
  138.         if(!isarea(ff.ff_name) && !mf_exclude(ff.ff_name)) {
  139.         if((strlen(ax_mftext) + strlen(ff.ff_name)) > MAXMFLEN - 1)
  140.             break; /* That's all folks */
  141.         if(checknewmail(ff.ff_name)) {
  142.             strcat(ax_mftext," ");
  143. #ifdef UNIX
  144.             /* upcase it, looks better */
  145.             for (d = 0; ax_mftext[d]; d++)
  146.             ;
  147.             for (c = 0; ff.ff_name[c]; c++)
  148.             ax_mftext[d++] = toupper(ff.ff_name[c]);
  149.             ax_mftext[d] = 0;
  150. #else
  151.             strcat(ax_mftext,ff.ff_name);
  152. #endif
  153.         }
  154.         }
  155.        } while (findnext(&ff) == 0);
  156.     }
  157.     return strlen(ax_mftext);
  158. }
  159.  
  160. /*This is the low-level broadcast function.*/
  161. void
  162. #ifdef PROTOTYPES
  163. ax_mf(struct iface *ifp)
  164. #else
  165. ax_mf(ifp)
  166. struct iface *ifp;
  167. #endif
  168. {
  169.     struct mbuf *bp;
  170.  
  171.     /* prepare the header */
  172.     if((bp = alloc_mbuf(mflen)) == NULLBUF)
  173.         return;
  174.  
  175.     /*copy the data into the packet*/
  176.     bp->cnt = mflen;
  177.     memcpy(bp->data,ax_mftext,(unsigned)mflen);
  178.  
  179.     /* send it */
  180.     (*ifp->output)(ifp, Ax25multi[MAILCALL], ifp->hwaddr,
  181.     PID_NO_L3, bp);
  182. }
  183.  
  184. void
  185. #ifdef PROTOTYPES
  186. Mftick(void *v)
  187. #else
  188. Mftick(v)
  189. void *v;
  190. #endif
  191. {
  192.     struct iface *ifp = Ifaces;
  193.  
  194.     stop_timer(&Mftimer); /* in case this was 'kicked' with a 'mailfor now'*/
  195.  
  196.     /*Now find private mail areas with unread mail.
  197.      *add these to the info-line
  198.      */
  199.     ax_mftext[DEFMFLEN] = '\0'; /* Back to only 'Mail for:' again*/
  200.     if((mflen=setmailfor()) < DEFMFLEN+1) {
  201.     start_timer(&Mftimer);
  202.     return; /* No unread mail */
  203.     }
  204.  
  205.     /*broadcast it on all condifured interfaces*/
  206.     for(ifp=Ifaces;ifp != NULL;ifp=ifp->next)
  207.     if(ifp->flags & MAIL_BEACON)
  208.         ax_mf(ifp);
  209.     /* Restart timer */
  210.     start_timer(&Mftimer) ;
  211. }
  212.  
  213. int
  214. #ifdef PROTOTYPES
  215. dombmailfor(int argc,char **argv,void *p)
  216. #else
  217. dombmailfor(argc,argv,p)
  218. int argc;
  219. char *argv[];
  220. void *p;
  221. #endif
  222. {
  223.     register int i;
  224.     struct no_mf *nm;
  225.  
  226.     if(argc < 2){
  227.     tprintf("Mail-for timer: %lu/%lu\n",
  228.     read_timer(&Mftimer)/1000L,
  229.     dur_timer(&Mftimer)/1000L);
  230.     if(mflen > DEFMFLEN)
  231.         tprintf("%s\n",ax_mftext);
  232.     return 0;
  233.     }
  234.     if(*argv[1] == 'n') { /*send mailfor 'now' !!*/
  235.     Mftick(NULL);
  236.     return 0;
  237.     }
  238.     if(*argv[1] == 'e') { /*exclude list */
  239.     /*the exclude subcommand*/
  240.     if(argc == 2) { /*just list them*/
  241.         for(nm=No_mf;nm!=NULLMF;nm=nm->next)
  242.         tprintf("%s ",nm->area);
  243.         tputc('\n');
  244.     } else { /*add some call(s)*/
  245.         for(i=0;i<argc-2;i++) {
  246.         if(strlen(argv[i+2]) > 8) {
  247.             tprintf("Invalid: %s\n",argv[i+2]);
  248.             continue;
  249.         }
  250.         nm = callocw(1,sizeof(struct no_mf));
  251.         strcpy(nm->area,argv[i+2]);
  252.         /* add to list */
  253.         nm->next = No_mf;
  254.         No_mf = nm;
  255.         }
  256.     }
  257.     return 0;
  258.     }
  259.     /* set the timer */
  260.     Mftimer.func = (void (*)__ARGS((void *)))Mftick;/* what to call on timeout */
  261.     Mftimer.arg = NULL;        /* dummy value */
  262.     set_timer(&Mftimer,atol(argv[1])*1000L); /* set timer duration */
  263.     Mftick(NULL); /* Do one now and start it all!*/
  264.     return 0;
  265. }
  266. #endif /* AX25 */
  267. #endif /* MAILFOR */
  268.  
  269. /*************************************************************************/
  270.  
  271. #ifdef RLINE
  272.  
  273. /* Depending on the flag set, the mailbox will
  274.  * read the message's original date,
  275.  * the correct 'from' address (instead of the user%forwardbbs@myhost),
  276.  * and for buls set the X-Forwarded options to prevent
  277.  * unneccesary forward attemps
  278.  * all from the R: lines supplied by the bbs system
  279.  * 920311 - WG7J
  280.  */
  281. static int dordate __ARGS((int argc,char *argv[],void *p));
  282. static int dorreturn __ARGS((int argc,char *argv[],void *p));
  283. static int dofwdcheck __ARGS((int argc,char *argv[],void *p));
  284. static int dombloophold __ARGS((int argc,char *argv[],void *p));
  285. static void ReadFwdBbs(void); 
  286.  
  287. char MyFwds[NUMFWDBBS][FWDBBSLEN+1];
  288. int Numfwds = 0;
  289. int Checklock = 0;   /* get increased to lock list of forward bbses */
  290. int Rdate = 0;
  291. int Rreturn = 0;
  292. int Rfwdcheck = 0;
  293.  
  294. static struct cmds Rlinetab[] = {
  295.     "check",    dofwdcheck,0, 0, NULLCHAR,
  296.     "date",     dordate,   0, 0, NULLCHAR,
  297.     "loophold", dombloophold,0,0, NULLCHAR,
  298.     "return",   dorreturn, 0, 0, NULLCHAR,
  299.     NULLCHAR,
  300. };
  301.  
  302. static int
  303. dordate(argc,argv,p)
  304. int argc;
  305. char *argv[];
  306. void *p;
  307. {
  308.     return setbool(&Rdate,"Use R: for orig. date",argc,argv);
  309. }
  310.  
  311. int Mbloophold = 2;
  312.  
  313. /* set loop detection threshold - WG7J */
  314. static int
  315. dombloophold(int argc,char *argv[],void *p)
  316. {
  317.     return setint(&Mbloophold,"Loop hold after",argc,argv);
  318. }
  319.  
  320. static int
  321. dorreturn(argc,argv,p)
  322. int argc;
  323. char *argv[];
  324. void *p;
  325. {
  326.     return setbool(&Rreturn,"Use R: for ret. addr.",argc,argv);
  327. }
  328.  
  329.  
  330. static int
  331. dofwdcheck(argc,argv,p)
  332. int argc;
  333. char *argv[];
  334. void *p;
  335. {
  336.     register int i;
  337.  
  338.     setbool(&Rfwdcheck,"Use R: to check buls",argc,argv);
  339.     if((argc == 1) && Rfwdcheck && Numfwds) { /*list the bbses we check*/
  340.     tputs("Checking for:");
  341.     for(i=0;i<Numfwds;i++)
  342.         tprintf(" %s",MyFwds[i]);
  343.     tputc('\n');
  344.     } else {
  345.     if(Rfwdcheck)
  346.         ReadFwdBbs();
  347.     }
  348.     return 0;
  349. }
  350.  
  351. int
  352. #ifdef PROTOTYPES
  353. dombrline(int argc,char **argv,void *p)
  354. #else
  355. dombrline(argc,argv,p)
  356. int argc;
  357. char *argv[];
  358. void *p;
  359. #endif
  360. {
  361.     return subcmd(Rlinetab,argc,argv,p);
  362. }
  363.  
  364. static void
  365. ReadFwdBbs() {
  366.     FILE *fp;
  367.     int start = 1;
  368.     char *cp;
  369.     char line[80];
  370.  
  371.     if(Checklock) {
  372.     tputs("Bbs-list locked, forward.bbs not re-read\n");
  373.     return;
  374.     }
  375.     Numfwds = 0;    /* reset */
  376.     if((fp=fopen(Forwardfile,READ_TEXT)) == NULLFILE) {
  377.     tputs("forward.bbs not found\n");
  378.     return;
  379.     }
  380.     /*Now scan the forward.bbs file to find bbs's*/
  381.     while(fgets(line,sizeof(line),fp) != NULLCHAR && (Numfwds < NUMFWDBBS)) {
  382.     if(*line == '\n')
  383.         continue;
  384.     /* lines starting with '-' separate the forwarding records */
  385.     if(*line == '-') {
  386.         start = 1;
  387.         continue;
  388.     }
  389.     if(start) {
  390.         start = 0;
  391.         /* get the name of this forwarding record */
  392.         if((cp=strchr(line,'\n')) != NULLCHAR)
  393.         *cp = '\0';
  394.         if((cp=strchr(line,' ')) != NULLCHAR)
  395.         *cp = '\0';
  396.         if((cp=strchr(line,'\t')) != NULLCHAR)
  397.         *cp = '\0';
  398.         if(strlen(line) > FWDBBSLEN)
  399.         continue;   /*What kind of bbs-call is this ?*/
  400.         strcpy(MyFwds[Numfwds++],strupr(line));
  401.     }
  402.     }
  403.     fclose(fp);
  404.     return;
  405. }
  406.  
  407. #endif /* RLINE */
  408.